package com.shoukaiseki.test.spring.redis.config;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import javax.inject.Named;
import java.time.Duration;

/**
 * <br>
 *
 * @author 蒋カイセキ    Japan-Tokyo  18-11-12 下午6:32<br>
 * ブログ http://www.shoukaiseki.top/<br>
 * E-メール jiang28555@Gmail.com<br>
 **/
@Configuration
//@EnableCaching
public class RedisConfig {

    @Bean("shoukaisekiRedisProperties")
    @ConfigurationProperties(prefix = "shoukaiseki.redis")
    public RedisProperties shoukaisekiRedisProperties(){
        return new RedisProperties();
    }

    private final static Logger log = LoggerFactory.getLogger(RedisConfig.class);


    @Bean(name = "shoukaisekiRedisConnectionFactory")
    public JedisConnectionFactory shoukaisekiRedisConnectionFactory(@Named("shoukaisekiRedisProperties") RedisProperties redisProperties) {
        if(log.isDebugEnabled()){
            log.info("redisProperties={}", JSONObject.toJSONString(redisProperties));
        }
        RedisStandaloneConfiguration standaloneConfig=redisProperties.getStandaloneConfig();
//
        standaloneConfig.setPassword(RedisPassword.of(redisProperties.getPassword()));


        JedisPoolConfig poolConfig ;
        poolConfig=redisProperties.getPoolConfig();

        JedisClientConfiguration jedisClientConfiguration = JedisClientConfiguration.builder().usePooling().poolConfig(poolConfig)
                .and().readTimeout(Duration.ofMillis(redisProperties.getReadTimeout())).connectTimeout(Duration.ofMillis(redisProperties.getConnectTimeout())).build();



        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(standaloneConfig,jedisClientConfiguration);
//        jedisConnectionFactory.setTimeout(redisProperties.getTimeout());
//        jedisConnectionFactory.setPoolConfig(poolConfig);
        return jedisConnectionFactory;
    }

//    /**
//     * 配置CacheManager,缓存管理器
//     *
//     * @param jedisConnectionFactory
//     * @return
//     */
//    @Bean
//    public CacheManager cacheManager(@Named("shoukaisekiRedisConnectionFactory") JedisConnectionFactory jedisConnectionFactory) {
//        RedisCacheManager redisCacheManager = RedisCacheManager.create(jedisConnectionFactory);
//        return redisCacheManager;
//    }

    @Bean("shoukaisekiRedisTemplate")
    public RedisTemplate<String, Object> shoukaisekiRedisTemplate(@Named("shoukaisekiRedisConnectionFactory") RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        //设置序列号方式
        setSerializer(redisTemplate);
        return redisTemplate;
    }




    @Bean("shoukaisekiStringRedisTemplate")
    public StringRedisTemplate shoukaisekiStringRedisTemplate(@Named("shoukaisekiRedisConnectionFactory") RedisConnectionFactory factory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }

    /**
     * 设置RedisTemplate的序列化方式
     *
     * @param redisTemplate
     */
    public void setSerializer(RedisTemplate redisTemplate) {
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //设置键（key）的序列化方式
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置值（value）的序列化方式
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
    }
}

